package edu.doeacc.tms.web.bean;

import java.io.Serializable;
import java.util.List;

import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.servlet.http.HttpServletRequest;

import edu.doeacc.tms.domain.Role;
import edu.doeacc.tms.domain.User;
import edu.doeacc.tms.service.dao.UserFacade;
import edu.doeacc.tms.web.util.JsfUtil;

@ManagedBean(name = "userBean")
@ViewScoped
public class UserBean implements Serializable {

    private User current;
    private User loggedInUser;

    private List<User> items = null;
    private List<Role> roles = null;

    @EJB
    private transient UserFacade userFacade;

    @ManagedProperty("#{msgs}")
    private transient ResourceBundle bundle;

    public UserBean() {
    }

    public void setBundle(ResourceBundle bundle) {
        this.bundle = bundle;
    }

    public User getSelected() {
        if (current == null) {
            if (this.currentUserId != null) {
                this.current = getFacade().find(this.currentUserId);
            } else {
                current = new User();
            }
        }
        return current;
    }

    public UserFacade getFacade() {
        return userFacade;
    }

    public String prepareList() {
        recreateModel();
        return "pretty:listUsers";
    }

    public String prepareCreate() {
        current = new User();
        return "pretty:addUser";
    }

    public User getLoggedInUser() {
        if (loggedInUser == null) {
            loggedInUser = getFacade().find(((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getUserPrincipal().getName());
        }
        return loggedInUser;
    }

    public String changePassword() {
        if (loggedInUser != null) {
            getFacade().editSelf(loggedInUser);
            loggedInUser = null;
        }
        return "pretty:home";
    }
    
    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(bundle.getString("UserCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, bundle.getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String prepareEdit(String id) {
        current = getFacade().find(id);
        return "pretty:editUser";
    }

    public String update() {
        try {
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(bundle.getString("UserUpdated"));
            return "pretty:listUsers";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, bundle.getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy(String id) {
        current = (User) getFacade().find(id);
        performDestroy();
        recreateModel();
        return "pretty:listUsers";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        return "pretty:listUsers";

    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage(bundle.getString("UserDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, bundle.getString("PersistenceErrorOccured"));
        }
    }

    public List<User> getItems() {
        if (items == null) {
            items = getFacade().findAll();
        }
        return items;
    }

    public List<Role> getRoles() {
        if (roles == null) {
            roles = getFacade().findAllRoles();
        }
        return roles;
    }

    private void recreateModel() {
        items = null;
    }

    @FacesConverter(forClass = Role.class)
    public static class RoleConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            UserBean controller = (UserBean) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "userBean");
            return controller.userFacade.findRole(value);
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Role) {
                Role o = (Role) object;
                return o.getRoleId();
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Role.class.getName());
            }
        }
    }
    String currentUserId = null;

    public String getCurrentUserId() {
        return getSelected().getLoginId();
    }

    public void setCurrentUserId(String id) {
        this.currentUserId = id;
    }
}
